#!/bin/sh

. "$SPEC_PATH/abstract/patroni"

. "$SPEC_PATH/abstract/sql-scripts"

e2e_test_extra_hash() {
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/abstract/patroni")"
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/abstract/sql-scripts")"
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/sql-scripts.sakila.sql")"
}

e2e_exclusive_lock() {
  true
}

e2e_test_install() {
  if [ "$(uname -m)" = "aarch64" ]
  then
    return
  fi
  CLUSTER_NAME="$(get_sgshardedcluster_name "$SPEC_NAME")"

  k8s_cleanup_namespace "$OPERATOR_NAMESPACE"
  k8s_async_cleanup

  kubectl create namespace "$OPERATOR_NAMESPACE"

  install_operator_only

  install_shardingsphere_operator

  install_minio

  cat << 'EOF' | kubectl create -n "$CLUSTER_NAMESPACE" secret generic sql-scripts-sakila-user \
    --from-literal=create-sakila-user.sql="$(cat)"
DO $$
BEGIN
  IF NOT EXISTS (SELECT * FROM pg_catalog.pg_roles WHERE rolname = 'sakila') THEN
    EXECUTE 'CREATE USER sakila WITH PASSWORD ''sakila'';';
  END IF;
END$$;
EOF

  kubectl create -n "$CLUSTER_NAMESPACE" configmap sql-scripts-sakila-schema \
    --from-file=create-sakila-schema.sql="$SPEC_PATH/sql-scripts.sakila.sql"

  create_or_replace_sharded_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE" "3" "2" \
    --set-string "cluster.configurations.shardingSphere.mode.repository.zooKeeper.serverList[0]=shardingsphere-operator-zookeeper.$(shardingsphere_namespace)"

  deploy_curl_pod "$CLUSTER_NAMESPACE"
  deploy_psql_pod "$CLUSTER_NAMESPACE"

  wait_pods_running "$CLUSTER_NAMESPACE" 8
  wait_sharded_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"
}

e2e_test() {
  if [ "$(uname -m)" = "aarch64" ]
  then
    echo "Skipping for aarch64"
    return
  fi

  run_test "Checking that is possible to connect using services is working" service_check

  run_test "Checking that sharded technology is configured and working" sharded_check

  run_test "Checking that managed SQL is working" check_managed_sql_is_working
}

service_check() {
  RESPONSE_PRIMARY="$(wait_until eval 'run_query -c "$CLUSTER_NAME" -x psql -k postgres -h "$CLUSTER_NAME" -p 5432')"

  if [ "$RESPONSE_PRIMARY" = "1" ]
  then
    success "Connections are possible using services"
  else
    fail "Cannot connect to primary db using a kubernetes service"
  fi
}

sharded_check() {
  local RESULT EXIT_CODE
  try_function wait_until eval "run_query -c '$CLUSTER_NAME-shard0' -h '$CLUSTER_NAME' -i 1 -p 5432 \
    -d postgres -q \"SHOW STORAGE UNITS\" | wc -l | grep -xF 2"

  if [ "$EXIT_CODE" = 0 ]
  then
    success "Sharding coordinator service is working"
  else
    fail "Sharding coordinator service is not working"
  fi

  try_function wait_until eval 'run_query -c "$CLUSTER_NAME-shard0" -h "$CLUSTER_NAME-shards" -i 1 -p 5432 \
    -d shardingsphere -q "SELECT pg_is_in_recovery()" | grep -xF f'

  if [ "$EXIT_CODE" = 0 ]
  then
    success "Sharding shards service is working"
  else
    fail "Sharding shards service is not working"
  fi
}

check_managed_sql_is_working() {
  local NODE=0
  local DATABASE=postgres
  check_user_on_sharded_primary "$CLUSTER_NAME" "$CLUSTER_NAME-shard0"
  check_database_on_sharded_primary "$CLUSTER_NAME" "$CLUSTER_NAME-shard0"
  check_schema_on_sharded_primary "$CLUSTER_NAME" "$CLUSTER_NAME-shard0"
}
